#For trace file generator
#Reference usage:
#python3 signal_file_gen.py -path /home/gary/Code/dataset/radar/diff_ratio/cons10M_101010.txt -type cons -start 0 -gauss=10 -miss=10 -noise=10 -len=10000000

import argparse
import random
from math import sin,pi
import numpy as np
import random

constant = [200]
sliding = [100, 150, 200, 250, 300]
ds = [110]*6 + [190]*6 + [320]*6
wobulated = []
#add in wobulated
for i in range(30):
    wobulated.append(int(150*sin(i*pi/15))+200)

if __name__=="__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('-path', type=str, default = "./signals.txt")
    parser.add_argument('-lable_path', type=str, default = None) #store the true TOA
    parser.add_argument('-type', type=str, default = None)
    parser.add_argument('-start', type=int, default = 0) #how many TOA start to generate
    parser.add_argument('-gauss', type=int, default = 10)
    parser.add_argument('-miss', type=int, default = 10)
    parser.add_argument('-noise', type=int, default = 10)
    parser.add_argument('-len', type=int, default = 1000000) #how many signal, default 1M
    parser.add_argument('-twin', type=int, default = 10) #time window
    parser.add_argument('-rootpath', type=str, default = None) #if root path is given, auto generate file name
    
    args = parser.parse_args()
    print("PRI type:",args.type)
    print("TOA Start:",args.start)
    print("TOA Length:",args.len)
    print("Gauss:",args.gauss,"Miss:",args.miss,"Noise:",args.noise)

    if(args.type == None):
        print("Please input pri type")
        quit()

    pri_list = None
    if(args.type in "constant"):
        pri_list = constant
    elif(args.type in "sliding"):
        pri_list = sliding
    elif(args.type in "ds"):
        pri_list = ds
    elif(args.type in "wobulated"):
        pri_list = wobulated
    else:
        print("Error PRI type:",args.type)
        quit()

    print("Generate by PRI:",pri_list)

    if(args.lable_path != None):
        print("Write lable file at",args.lable_path,", time window",args.twin)

        TOA_list = []
        toa = 0
        for i in range(args.len):
            TOA_list.append(toa)
            toa += pri_list[i%len(pri_list)]

        #将TOA转化为二进制编码
        def TOA_to_Binary(TOA_list,time_window_size,length): #time_window_size为每个数组所代表的窗口大小，length是这个TOA_list总共包含多少个时间窗口
            Binary_list = [0]*length
            for TOA in TOA_list:
                index = int(TOA//time_window_size)
                if(index < length):
                    Binary_list[index-1] = 1
                else:
                    break
            return Binary_list
        
        TOA_list = TOA_to_Binary(TOA_list,args.twin,args.len)

        with open(args.lable_path,"w") as fd:
            for line in TOA_list:
                fd.write(str(line)+"\n")

        print("Write Done")

        quit()
    
    #如果指定了根目录，则自动根据参数生成文件名
    #格式为<type><length>_<gauss><miss><noise>.txt
    trace_path = args.path
    if(args.rootpath != None):
        trace_path = args.rootpath + '/'
        trace_path += args.type

        trace_len = args.len
        unit = ''
        if(trace_len >= 1000*1000*1000):
            unit = 'G'
            trace_len = trace_len//(1000*1000*1000)
        elif(trace_len >= 1000*1000):
            unit = 'M'
            trace_len = trace_len//(1000*1000)
        elif(trace_len >= 1000):
            unit = 'K'
            trace_len = trace_len//1000

        trace_path += str(trace_len) + unit + '_'
        trace_path += str(args.gauss).zfill(2) + str(args.miss).zfill(2) + str(args.noise).zfill(2)
        trace_path += '.txt'

    print("Write into:",trace_path)
    f = open(trace_path,"w")

    origin_toa = args.start
    fake_toa = origin_toa
    error_list_length = 100 #高斯误差生成周期
    error_list = []

    total_toa = 0
    loss_toa = 0
    noise_toa = 0

    tenpercent = args.len//10
    processing = 0
    for i in range(args.len):
        if(i%tenpercent == 0):
            print("Finished:",processing,"%")
            processing += 10

        fake_toa = origin_toa
        #添加高斯误差
        if(i%error_list_length==0):
            error_list = list(np.random.normal(0, args.gauss, error_list_length))
        fake_toa = max(int(fake_toa+error_list.pop()),0)

        #添加丢失脉冲，如果落入范围内则不插入
        if(random.randint(0,100)<args.miss):
            loss_toa += 1
            continue

        #添加虚假脉冲，如果落入范围内则插入一个比fake_toa少50us的脉冲。如果插入大50us的那时间顺序就乱了
        if(random.randint(0,100)<args.noise):
            noise_toa += 1
            f.write(str(max(fake_toa-50,0))+"\n")
            total_toa += 1

        f.write(str(fake_toa)+"\n")
        total_toa += 1

        origin_toa+=pri_list[i%len(pri_list)]

    f.close()

    print("Generate Done,total",total_toa,"signals")
    print("Miss:",loss_toa,"Noise:",noise_toa)
    print("TOA range:[",args.start,",",fake_toa,"]")
    with open("toa_start.txt","w") as f:
        f.write(str(fake_toa))

    


